{
 "cells": [
  {
   "cell_type": "markdown",
   "source": [
    "This guide assumes familiarity with the following concepts:\n",
    "\n",
    "- [LangChain Tools](https://python.langchain.com/docs/concepts/tools/)\n",
    "- [LangChain Toolkits](https://python.langchain.com/docs/concepts/tools/)"
   ],
   "metadata": {
    "collapsed": false
   },
   "id": "c36632fa1185e2e3"
  },
  {
   "cell_type": "code",
   "outputs": [
    {
     "ename": "ConnectTimeout",
     "evalue": "HTTPConnectionPool(host='en.wikipedia.org', port=80): Max retries exceeded with url: /w/api.php?list=search&srprop=&srlimit=1&limit=1&srsearch=langchain&format=json&action=query (Caused by ConnectTimeoutError(<urllib3.connection.HTTPConnection object at 0x110d94980>, 'Connection to en.wikipedia.org timed out. (connect timeout=None)'))",
     "output_type": "error",
     "traceback": [
      "\u001B[0;31m---------------------------------------------------------------------------\u001B[0m",
      "\u001B[0;31mTimeoutError\u001B[0m                              Traceback (most recent call last)",
      "File \u001B[0;32m/opt/anaconda3/envs/ai_312/lib/python3.12/site-packages/urllib3/connection.py:199\u001B[0m, in \u001B[0;36mHTTPConnection._new_conn\u001B[0;34m(self)\u001B[0m\n\u001B[1;32m    198\u001B[0m \u001B[38;5;28;01mtry\u001B[39;00m:\n\u001B[0;32m--> 199\u001B[0m     sock \u001B[38;5;241m=\u001B[39m connection\u001B[38;5;241m.\u001B[39mcreate_connection(\n\u001B[1;32m    200\u001B[0m         (\u001B[38;5;28mself\u001B[39m\u001B[38;5;241m.\u001B[39m_dns_host, \u001B[38;5;28mself\u001B[39m\u001B[38;5;241m.\u001B[39mport),\n\u001B[1;32m    201\u001B[0m         \u001B[38;5;28mself\u001B[39m\u001B[38;5;241m.\u001B[39mtimeout,\n\u001B[1;32m    202\u001B[0m         source_address\u001B[38;5;241m=\u001B[39m\u001B[38;5;28mself\u001B[39m\u001B[38;5;241m.\u001B[39msource_address,\n\u001B[1;32m    203\u001B[0m         socket_options\u001B[38;5;241m=\u001B[39m\u001B[38;5;28mself\u001B[39m\u001B[38;5;241m.\u001B[39msocket_options,\n\u001B[1;32m    204\u001B[0m     )\n\u001B[1;32m    205\u001B[0m \u001B[38;5;28;01mexcept\u001B[39;00m socket\u001B[38;5;241m.\u001B[39mgaierror \u001B[38;5;28;01mas\u001B[39;00m e:\n",
      "File \u001B[0;32m/opt/anaconda3/envs/ai_312/lib/python3.12/site-packages/urllib3/util/connection.py:85\u001B[0m, in \u001B[0;36mcreate_connection\u001B[0;34m(address, timeout, source_address, socket_options)\u001B[0m\n\u001B[1;32m     84\u001B[0m \u001B[38;5;28;01mtry\u001B[39;00m:\n\u001B[0;32m---> 85\u001B[0m     \u001B[38;5;28;01mraise\u001B[39;00m err\n\u001B[1;32m     86\u001B[0m \u001B[38;5;28;01mfinally\u001B[39;00m:\n\u001B[1;32m     87\u001B[0m     \u001B[38;5;66;03m# Break explicitly a reference cycle\u001B[39;00m\n",
      "File \u001B[0;32m/opt/anaconda3/envs/ai_312/lib/python3.12/site-packages/urllib3/util/connection.py:73\u001B[0m, in \u001B[0;36mcreate_connection\u001B[0;34m(address, timeout, source_address, socket_options)\u001B[0m\n\u001B[1;32m     72\u001B[0m     sock\u001B[38;5;241m.\u001B[39mbind(source_address)\n\u001B[0;32m---> 73\u001B[0m sock\u001B[38;5;241m.\u001B[39mconnect(sa)\n\u001B[1;32m     74\u001B[0m \u001B[38;5;66;03m# Break explicitly a reference cycle\u001B[39;00m\n",
      "\u001B[0;31mTimeoutError\u001B[0m: [Errno 60] Operation timed out",
      "\nThe above exception was the direct cause of the following exception:\n",
      "\u001B[0;31mConnectTimeoutError\u001B[0m                       Traceback (most recent call last)",
      "File \u001B[0;32m/opt/anaconda3/envs/ai_312/lib/python3.12/site-packages/urllib3/connectionpool.py:789\u001B[0m, in \u001B[0;36mHTTPConnectionPool.urlopen\u001B[0;34m(self, method, url, body, headers, retries, redirect, assert_same_host, timeout, pool_timeout, release_conn, chunked, body_pos, preload_content, decode_content, **response_kw)\u001B[0m\n\u001B[1;32m    788\u001B[0m \u001B[38;5;66;03m# Make the request on the HTTPConnection object\u001B[39;00m\n\u001B[0;32m--> 789\u001B[0m response \u001B[38;5;241m=\u001B[39m \u001B[38;5;28mself\u001B[39m\u001B[38;5;241m.\u001B[39m_make_request(\n\u001B[1;32m    790\u001B[0m     conn,\n\u001B[1;32m    791\u001B[0m     method,\n\u001B[1;32m    792\u001B[0m     url,\n\u001B[1;32m    793\u001B[0m     timeout\u001B[38;5;241m=\u001B[39mtimeout_obj,\n\u001B[1;32m    794\u001B[0m     body\u001B[38;5;241m=\u001B[39mbody,\n\u001B[1;32m    795\u001B[0m     headers\u001B[38;5;241m=\u001B[39mheaders,\n\u001B[1;32m    796\u001B[0m     chunked\u001B[38;5;241m=\u001B[39mchunked,\n\u001B[1;32m    797\u001B[0m     retries\u001B[38;5;241m=\u001B[39mretries,\n\u001B[1;32m    798\u001B[0m     response_conn\u001B[38;5;241m=\u001B[39mresponse_conn,\n\u001B[1;32m    799\u001B[0m     preload_content\u001B[38;5;241m=\u001B[39mpreload_content,\n\u001B[1;32m    800\u001B[0m     decode_content\u001B[38;5;241m=\u001B[39mdecode_content,\n\u001B[1;32m    801\u001B[0m     \u001B[38;5;241m*\u001B[39m\u001B[38;5;241m*\u001B[39mresponse_kw,\n\u001B[1;32m    802\u001B[0m )\n\u001B[1;32m    804\u001B[0m \u001B[38;5;66;03m# Everything went great!\u001B[39;00m\n",
      "File \u001B[0;32m/opt/anaconda3/envs/ai_312/lib/python3.12/site-packages/urllib3/connectionpool.py:495\u001B[0m, in \u001B[0;36mHTTPConnectionPool._make_request\u001B[0;34m(self, conn, method, url, body, headers, retries, timeout, chunked, response_conn, preload_content, decode_content, enforce_content_length)\u001B[0m\n\u001B[1;32m    494\u001B[0m \u001B[38;5;28;01mtry\u001B[39;00m:\n\u001B[0;32m--> 495\u001B[0m     conn\u001B[38;5;241m.\u001B[39mrequest(\n\u001B[1;32m    496\u001B[0m         method,\n\u001B[1;32m    497\u001B[0m         url,\n\u001B[1;32m    498\u001B[0m         body\u001B[38;5;241m=\u001B[39mbody,\n\u001B[1;32m    499\u001B[0m         headers\u001B[38;5;241m=\u001B[39mheaders,\n\u001B[1;32m    500\u001B[0m         chunked\u001B[38;5;241m=\u001B[39mchunked,\n\u001B[1;32m    501\u001B[0m         preload_content\u001B[38;5;241m=\u001B[39mpreload_content,\n\u001B[1;32m    502\u001B[0m         decode_content\u001B[38;5;241m=\u001B[39mdecode_content,\n\u001B[1;32m    503\u001B[0m         enforce_content_length\u001B[38;5;241m=\u001B[39menforce_content_length,\n\u001B[1;32m    504\u001B[0m     )\n\u001B[1;32m    506\u001B[0m \u001B[38;5;66;03m# We are swallowing BrokenPipeError (errno.EPIPE) since the server is\u001B[39;00m\n\u001B[1;32m    507\u001B[0m \u001B[38;5;66;03m# legitimately able to close the connection after sending a valid response.\u001B[39;00m\n\u001B[1;32m    508\u001B[0m \u001B[38;5;66;03m# With this behaviour, the received response is still readable.\u001B[39;00m\n",
      "File \u001B[0;32m/opt/anaconda3/envs/ai_312/lib/python3.12/site-packages/urllib3/connection.py:441\u001B[0m, in \u001B[0;36mHTTPConnection.request\u001B[0;34m(self, method, url, body, headers, chunked, preload_content, decode_content, enforce_content_length)\u001B[0m\n\u001B[1;32m    440\u001B[0m     \u001B[38;5;28mself\u001B[39m\u001B[38;5;241m.\u001B[39mputheader(header, value)\n\u001B[0;32m--> 441\u001B[0m \u001B[38;5;28mself\u001B[39m\u001B[38;5;241m.\u001B[39mendheaders()\n\u001B[1;32m    443\u001B[0m \u001B[38;5;66;03m# If we're given a body we start sending that in chunks.\u001B[39;00m\n",
      "File \u001B[0;32m/opt/anaconda3/envs/ai_312/lib/python3.12/http/client.py:1331\u001B[0m, in \u001B[0;36mHTTPConnection.endheaders\u001B[0;34m(self, message_body, encode_chunked)\u001B[0m\n\u001B[1;32m   1330\u001B[0m     \u001B[38;5;28;01mraise\u001B[39;00m CannotSendHeader()\n\u001B[0;32m-> 1331\u001B[0m \u001B[38;5;28mself\u001B[39m\u001B[38;5;241m.\u001B[39m_send_output(message_body, encode_chunked\u001B[38;5;241m=\u001B[39mencode_chunked)\n",
      "File \u001B[0;32m/opt/anaconda3/envs/ai_312/lib/python3.12/http/client.py:1091\u001B[0m, in \u001B[0;36mHTTPConnection._send_output\u001B[0;34m(self, message_body, encode_chunked)\u001B[0m\n\u001B[1;32m   1090\u001B[0m \u001B[38;5;28;01mdel\u001B[39;00m \u001B[38;5;28mself\u001B[39m\u001B[38;5;241m.\u001B[39m_buffer[:]\n\u001B[0;32m-> 1091\u001B[0m \u001B[38;5;28mself\u001B[39m\u001B[38;5;241m.\u001B[39msend(msg)\n\u001B[1;32m   1093\u001B[0m \u001B[38;5;28;01mif\u001B[39;00m message_body \u001B[38;5;129;01mis\u001B[39;00m \u001B[38;5;129;01mnot\u001B[39;00m \u001B[38;5;28;01mNone\u001B[39;00m:\n\u001B[1;32m   1094\u001B[0m \n\u001B[1;32m   1095\u001B[0m     \u001B[38;5;66;03m# create a consistent interface to message_body\u001B[39;00m\n",
      "File \u001B[0;32m/opt/anaconda3/envs/ai_312/lib/python3.12/http/client.py:1035\u001B[0m, in \u001B[0;36mHTTPConnection.send\u001B[0;34m(self, data)\u001B[0m\n\u001B[1;32m   1034\u001B[0m \u001B[38;5;28;01mif\u001B[39;00m \u001B[38;5;28mself\u001B[39m\u001B[38;5;241m.\u001B[39mauto_open:\n\u001B[0;32m-> 1035\u001B[0m     \u001B[38;5;28mself\u001B[39m\u001B[38;5;241m.\u001B[39mconnect()\n\u001B[1;32m   1036\u001B[0m \u001B[38;5;28;01melse\u001B[39;00m:\n",
      "File \u001B[0;32m/opt/anaconda3/envs/ai_312/lib/python3.12/site-packages/urllib3/connection.py:279\u001B[0m, in \u001B[0;36mHTTPConnection.connect\u001B[0;34m(self)\u001B[0m\n\u001B[1;32m    278\u001B[0m \u001B[38;5;28;01mdef\u001B[39;00m \u001B[38;5;21mconnect\u001B[39m(\u001B[38;5;28mself\u001B[39m) \u001B[38;5;241m-\u001B[39m\u001B[38;5;241m>\u001B[39m \u001B[38;5;28;01mNone\u001B[39;00m:\n\u001B[0;32m--> 279\u001B[0m     \u001B[38;5;28mself\u001B[39m\u001B[38;5;241m.\u001B[39msock \u001B[38;5;241m=\u001B[39m \u001B[38;5;28mself\u001B[39m\u001B[38;5;241m.\u001B[39m_new_conn()\n\u001B[1;32m    280\u001B[0m     \u001B[38;5;28;01mif\u001B[39;00m \u001B[38;5;28mself\u001B[39m\u001B[38;5;241m.\u001B[39m_tunnel_host:\n\u001B[1;32m    281\u001B[0m         \u001B[38;5;66;03m# If we're tunneling it means we're connected to our proxy.\u001B[39;00m\n",
      "File \u001B[0;32m/opt/anaconda3/envs/ai_312/lib/python3.12/site-packages/urllib3/connection.py:208\u001B[0m, in \u001B[0;36mHTTPConnection._new_conn\u001B[0;34m(self)\u001B[0m\n\u001B[1;32m    207\u001B[0m \u001B[38;5;28;01mexcept\u001B[39;00m SocketTimeout \u001B[38;5;28;01mas\u001B[39;00m e:\n\u001B[0;32m--> 208\u001B[0m     \u001B[38;5;28;01mraise\u001B[39;00m ConnectTimeoutError(\n\u001B[1;32m    209\u001B[0m         \u001B[38;5;28mself\u001B[39m,\n\u001B[1;32m    210\u001B[0m         \u001B[38;5;124mf\u001B[39m\u001B[38;5;124m\"\u001B[39m\u001B[38;5;124mConnection to \u001B[39m\u001B[38;5;132;01m{\u001B[39;00m\u001B[38;5;28mself\u001B[39m\u001B[38;5;241m.\u001B[39mhost\u001B[38;5;132;01m}\u001B[39;00m\u001B[38;5;124m timed out. (connect timeout=\u001B[39m\u001B[38;5;132;01m{\u001B[39;00m\u001B[38;5;28mself\u001B[39m\u001B[38;5;241m.\u001B[39mtimeout\u001B[38;5;132;01m}\u001B[39;00m\u001B[38;5;124m)\u001B[39m\u001B[38;5;124m\"\u001B[39m,\n\u001B[1;32m    211\u001B[0m     ) \u001B[38;5;28;01mfrom\u001B[39;00m \u001B[38;5;21;01me\u001B[39;00m\n\u001B[1;32m    213\u001B[0m \u001B[38;5;28;01mexcept\u001B[39;00m \u001B[38;5;167;01mOSError\u001B[39;00m \u001B[38;5;28;01mas\u001B[39;00m e:\n",
      "\u001B[0;31mConnectTimeoutError\u001B[0m: (<urllib3.connection.HTTPConnection object at 0x110d94980>, 'Connection to en.wikipedia.org timed out. (connect timeout=None)')",
      "\nThe above exception was the direct cause of the following exception:\n",
      "\u001B[0;31mMaxRetryError\u001B[0m                             Traceback (most recent call last)",
      "File \u001B[0;32m/opt/anaconda3/envs/ai_312/lib/python3.12/site-packages/requests/adapters.py:667\u001B[0m, in \u001B[0;36mHTTPAdapter.send\u001B[0;34m(self, request, stream, timeout, verify, cert, proxies)\u001B[0m\n\u001B[1;32m    666\u001B[0m \u001B[38;5;28;01mtry\u001B[39;00m:\n\u001B[0;32m--> 667\u001B[0m     resp \u001B[38;5;241m=\u001B[39m conn\u001B[38;5;241m.\u001B[39murlopen(\n\u001B[1;32m    668\u001B[0m         method\u001B[38;5;241m=\u001B[39mrequest\u001B[38;5;241m.\u001B[39mmethod,\n\u001B[1;32m    669\u001B[0m         url\u001B[38;5;241m=\u001B[39murl,\n\u001B[1;32m    670\u001B[0m         body\u001B[38;5;241m=\u001B[39mrequest\u001B[38;5;241m.\u001B[39mbody,\n\u001B[1;32m    671\u001B[0m         headers\u001B[38;5;241m=\u001B[39mrequest\u001B[38;5;241m.\u001B[39mheaders,\n\u001B[1;32m    672\u001B[0m         redirect\u001B[38;5;241m=\u001B[39m\u001B[38;5;28;01mFalse\u001B[39;00m,\n\u001B[1;32m    673\u001B[0m         assert_same_host\u001B[38;5;241m=\u001B[39m\u001B[38;5;28;01mFalse\u001B[39;00m,\n\u001B[1;32m    674\u001B[0m         preload_content\u001B[38;5;241m=\u001B[39m\u001B[38;5;28;01mFalse\u001B[39;00m,\n\u001B[1;32m    675\u001B[0m         decode_content\u001B[38;5;241m=\u001B[39m\u001B[38;5;28;01mFalse\u001B[39;00m,\n\u001B[1;32m    676\u001B[0m         retries\u001B[38;5;241m=\u001B[39m\u001B[38;5;28mself\u001B[39m\u001B[38;5;241m.\u001B[39mmax_retries,\n\u001B[1;32m    677\u001B[0m         timeout\u001B[38;5;241m=\u001B[39mtimeout,\n\u001B[1;32m    678\u001B[0m         chunked\u001B[38;5;241m=\u001B[39mchunked,\n\u001B[1;32m    679\u001B[0m     )\n\u001B[1;32m    681\u001B[0m \u001B[38;5;28;01mexcept\u001B[39;00m (ProtocolError, \u001B[38;5;167;01mOSError\u001B[39;00m) \u001B[38;5;28;01mas\u001B[39;00m err:\n",
      "File \u001B[0;32m/opt/anaconda3/envs/ai_312/lib/python3.12/site-packages/urllib3/connectionpool.py:843\u001B[0m, in \u001B[0;36mHTTPConnectionPool.urlopen\u001B[0;34m(self, method, url, body, headers, retries, redirect, assert_same_host, timeout, pool_timeout, release_conn, chunked, body_pos, preload_content, decode_content, **response_kw)\u001B[0m\n\u001B[1;32m    841\u001B[0m     new_e \u001B[38;5;241m=\u001B[39m ProtocolError(\u001B[38;5;124m\"\u001B[39m\u001B[38;5;124mConnection aborted.\u001B[39m\u001B[38;5;124m\"\u001B[39m, new_e)\n\u001B[0;32m--> 843\u001B[0m retries \u001B[38;5;241m=\u001B[39m retries\u001B[38;5;241m.\u001B[39mincrement(\n\u001B[1;32m    844\u001B[0m     method, url, error\u001B[38;5;241m=\u001B[39mnew_e, _pool\u001B[38;5;241m=\u001B[39m\u001B[38;5;28mself\u001B[39m, _stacktrace\u001B[38;5;241m=\u001B[39msys\u001B[38;5;241m.\u001B[39mexc_info()[\u001B[38;5;241m2\u001B[39m]\n\u001B[1;32m    845\u001B[0m )\n\u001B[1;32m    846\u001B[0m retries\u001B[38;5;241m.\u001B[39msleep()\n",
      "File \u001B[0;32m/opt/anaconda3/envs/ai_312/lib/python3.12/site-packages/urllib3/util/retry.py:519\u001B[0m, in \u001B[0;36mRetry.increment\u001B[0;34m(self, method, url, response, error, _pool, _stacktrace)\u001B[0m\n\u001B[1;32m    518\u001B[0m     reason \u001B[38;5;241m=\u001B[39m error \u001B[38;5;129;01mor\u001B[39;00m ResponseError(cause)\n\u001B[0;32m--> 519\u001B[0m     \u001B[38;5;28;01mraise\u001B[39;00m MaxRetryError(_pool, url, reason) \u001B[38;5;28;01mfrom\u001B[39;00m \u001B[38;5;21;01mreason\u001B[39;00m  \u001B[38;5;66;03m# type: ignore[arg-type]\u001B[39;00m\n\u001B[1;32m    521\u001B[0m log\u001B[38;5;241m.\u001B[39mdebug(\u001B[38;5;124m\"\u001B[39m\u001B[38;5;124mIncremented Retry for (url=\u001B[39m\u001B[38;5;124m'\u001B[39m\u001B[38;5;132;01m%s\u001B[39;00m\u001B[38;5;124m'\u001B[39m\u001B[38;5;124m): \u001B[39m\u001B[38;5;132;01m%r\u001B[39;00m\u001B[38;5;124m\"\u001B[39m, url, new_retry)\n",
      "\u001B[0;31mMaxRetryError\u001B[0m: HTTPConnectionPool(host='en.wikipedia.org', port=80): Max retries exceeded with url: /w/api.php?list=search&srprop=&srlimit=1&limit=1&srsearch=langchain&format=json&action=query (Caused by ConnectTimeoutError(<urllib3.connection.HTTPConnection object at 0x110d94980>, 'Connection to en.wikipedia.org timed out. (connect timeout=None)'))",
      "\nDuring handling of the above exception, another exception occurred:\n",
      "\u001B[0;31mConnectTimeout\u001B[0m                            Traceback (most recent call last)",
      "Cell \u001B[0;32mIn[2], line 7\u001B[0m\n\u001B[1;32m      4\u001B[0m api_wrapper \u001B[38;5;241m=\u001B[39m WikipediaAPIWrapper(top_k_results\u001B[38;5;241m=\u001B[39m\u001B[38;5;241m1\u001B[39m, doc_content_chars_max\u001B[38;5;241m=\u001B[39m\u001B[38;5;241m100\u001B[39m)\n\u001B[1;32m      5\u001B[0m tool \u001B[38;5;241m=\u001B[39m WikipediaQueryRun(api_wrapper\u001B[38;5;241m=\u001B[39mapi_wrapper)\n\u001B[0;32m----> 7\u001B[0m \u001B[38;5;28mprint\u001B[39m(tool\u001B[38;5;241m.\u001B[39minvoke({\u001B[38;5;124m\"\u001B[39m\u001B[38;5;124mquery\u001B[39m\u001B[38;5;124m\"\u001B[39m: \u001B[38;5;124m\"\u001B[39m\u001B[38;5;124mlangchain\u001B[39m\u001B[38;5;124m\"\u001B[39m}))\n",
      "File \u001B[0;32m/opt/anaconda3/envs/ai_312/lib/python3.12/site-packages/langchain_core/tools/base.py:484\u001B[0m, in \u001B[0;36mBaseTool.invoke\u001B[0;34m(self, input, config, **kwargs)\u001B[0m\n\u001B[1;32m    477\u001B[0m \u001B[38;5;28;01mdef\u001B[39;00m \u001B[38;5;21minvoke\u001B[39m(\n\u001B[1;32m    478\u001B[0m     \u001B[38;5;28mself\u001B[39m,\n\u001B[1;32m    479\u001B[0m     \u001B[38;5;28minput\u001B[39m: Union[\u001B[38;5;28mstr\u001B[39m, \u001B[38;5;28mdict\u001B[39m, ToolCall],\n\u001B[1;32m    480\u001B[0m     config: Optional[RunnableConfig] \u001B[38;5;241m=\u001B[39m \u001B[38;5;28;01mNone\u001B[39;00m,\n\u001B[1;32m    481\u001B[0m     \u001B[38;5;241m*\u001B[39m\u001B[38;5;241m*\u001B[39mkwargs: Any,\n\u001B[1;32m    482\u001B[0m ) \u001B[38;5;241m-\u001B[39m\u001B[38;5;241m>\u001B[39m Any:\n\u001B[1;32m    483\u001B[0m     tool_input, kwargs \u001B[38;5;241m=\u001B[39m _prep_run_args(\u001B[38;5;28minput\u001B[39m, config, \u001B[38;5;241m*\u001B[39m\u001B[38;5;241m*\u001B[39mkwargs)\n\u001B[0;32m--> 484\u001B[0m     \u001B[38;5;28;01mreturn\u001B[39;00m \u001B[38;5;28mself\u001B[39m\u001B[38;5;241m.\u001B[39mrun(tool_input, \u001B[38;5;241m*\u001B[39m\u001B[38;5;241m*\u001B[39mkwargs)\n",
      "File \u001B[0;32m/opt/anaconda3/envs/ai_312/lib/python3.12/site-packages/langchain_core/tools/base.py:689\u001B[0m, in \u001B[0;36mBaseTool.run\u001B[0;34m(self, tool_input, verbose, start_color, color, callbacks, tags, metadata, run_name, run_id, config, tool_call_id, **kwargs)\u001B[0m\n\u001B[1;32m    687\u001B[0m \u001B[38;5;28;01mif\u001B[39;00m error_to_raise:\n\u001B[1;32m    688\u001B[0m     run_manager\u001B[38;5;241m.\u001B[39mon_tool_error(error_to_raise)\n\u001B[0;32m--> 689\u001B[0m     \u001B[38;5;28;01mraise\u001B[39;00m error_to_raise\n\u001B[1;32m    690\u001B[0m output \u001B[38;5;241m=\u001B[39m _format_output(content, artifact, tool_call_id, \u001B[38;5;28mself\u001B[39m\u001B[38;5;241m.\u001B[39mname, status)\n\u001B[1;32m    691\u001B[0m run_manager\u001B[38;5;241m.\u001B[39mon_tool_end(output, color\u001B[38;5;241m=\u001B[39mcolor, name\u001B[38;5;241m=\u001B[39m\u001B[38;5;28mself\u001B[39m\u001B[38;5;241m.\u001B[39mname, \u001B[38;5;241m*\u001B[39m\u001B[38;5;241m*\u001B[39mkwargs)\n",
      "File \u001B[0;32m/opt/anaconda3/envs/ai_312/lib/python3.12/site-packages/langchain_core/tools/base.py:657\u001B[0m, in \u001B[0;36mBaseTool.run\u001B[0;34m(self, tool_input, verbose, start_color, color, callbacks, tags, metadata, run_name, run_id, config, tool_call_id, **kwargs)\u001B[0m\n\u001B[1;32m    655\u001B[0m \u001B[38;5;28;01mif\u001B[39;00m config_param \u001B[38;5;241m:=\u001B[39m _get_runnable_config_param(\u001B[38;5;28mself\u001B[39m\u001B[38;5;241m.\u001B[39m_run):\n\u001B[1;32m    656\u001B[0m     tool_kwargs[config_param] \u001B[38;5;241m=\u001B[39m config\n\u001B[0;32m--> 657\u001B[0m response \u001B[38;5;241m=\u001B[39m context\u001B[38;5;241m.\u001B[39mrun(\u001B[38;5;28mself\u001B[39m\u001B[38;5;241m.\u001B[39m_run, \u001B[38;5;241m*\u001B[39mtool_args, \u001B[38;5;241m*\u001B[39m\u001B[38;5;241m*\u001B[39mtool_kwargs)\n\u001B[1;32m    658\u001B[0m \u001B[38;5;28;01mif\u001B[39;00m \u001B[38;5;28mself\u001B[39m\u001B[38;5;241m.\u001B[39mresponse_format \u001B[38;5;241m==\u001B[39m \u001B[38;5;124m\"\u001B[39m\u001B[38;5;124mcontent_and_artifact\u001B[39m\u001B[38;5;124m\"\u001B[39m:\n\u001B[1;32m    659\u001B[0m     \u001B[38;5;28;01mif\u001B[39;00m \u001B[38;5;129;01mnot\u001B[39;00m \u001B[38;5;28misinstance\u001B[39m(response, \u001B[38;5;28mtuple\u001B[39m) \u001B[38;5;129;01mor\u001B[39;00m \u001B[38;5;28mlen\u001B[39m(response) \u001B[38;5;241m!=\u001B[39m \u001B[38;5;241m2\u001B[39m:\n",
      "File \u001B[0;32m/opt/anaconda3/envs/ai_312/lib/python3.12/site-packages/langchain_community/tools/wikipedia/tool.py:38\u001B[0m, in \u001B[0;36mWikipediaQueryRun._run\u001B[0;34m(self, query, run_manager)\u001B[0m\n\u001B[1;32m     32\u001B[0m \u001B[38;5;28;01mdef\u001B[39;00m \u001B[38;5;21m_run\u001B[39m(\n\u001B[1;32m     33\u001B[0m     \u001B[38;5;28mself\u001B[39m,\n\u001B[1;32m     34\u001B[0m     query: \u001B[38;5;28mstr\u001B[39m,\n\u001B[1;32m     35\u001B[0m     run_manager: Optional[CallbackManagerForToolRun] \u001B[38;5;241m=\u001B[39m \u001B[38;5;28;01mNone\u001B[39;00m,\n\u001B[1;32m     36\u001B[0m ) \u001B[38;5;241m-\u001B[39m\u001B[38;5;241m>\u001B[39m \u001B[38;5;28mstr\u001B[39m:\n\u001B[1;32m     37\u001B[0m \u001B[38;5;250m    \u001B[39m\u001B[38;5;124;03m\"\"\"Use the Wikipedia tool.\"\"\"\u001B[39;00m\n\u001B[0;32m---> 38\u001B[0m     \u001B[38;5;28;01mreturn\u001B[39;00m \u001B[38;5;28mself\u001B[39m\u001B[38;5;241m.\u001B[39mapi_wrapper\u001B[38;5;241m.\u001B[39mrun(query)\n",
      "File \u001B[0;32m/opt/anaconda3/envs/ai_312/lib/python3.12/site-packages/langchain_community/utilities/wikipedia.py:49\u001B[0m, in \u001B[0;36mWikipediaAPIWrapper.run\u001B[0;34m(self, query)\u001B[0m\n\u001B[1;32m     47\u001B[0m \u001B[38;5;28;01mdef\u001B[39;00m \u001B[38;5;21mrun\u001B[39m(\u001B[38;5;28mself\u001B[39m, query: \u001B[38;5;28mstr\u001B[39m) \u001B[38;5;241m-\u001B[39m\u001B[38;5;241m>\u001B[39m \u001B[38;5;28mstr\u001B[39m:\n\u001B[1;32m     48\u001B[0m \u001B[38;5;250m    \u001B[39m\u001B[38;5;124;03m\"\"\"Run Wikipedia search and get page summaries.\"\"\"\u001B[39;00m\n\u001B[0;32m---> 49\u001B[0m     page_titles \u001B[38;5;241m=\u001B[39m \u001B[38;5;28mself\u001B[39m\u001B[38;5;241m.\u001B[39mwiki_client\u001B[38;5;241m.\u001B[39msearch(\n\u001B[1;32m     50\u001B[0m         query[:WIKIPEDIA_MAX_QUERY_LENGTH], results\u001B[38;5;241m=\u001B[39m\u001B[38;5;28mself\u001B[39m\u001B[38;5;241m.\u001B[39mtop_k_results\n\u001B[1;32m     51\u001B[0m     )\n\u001B[1;32m     52\u001B[0m     summaries \u001B[38;5;241m=\u001B[39m []\n\u001B[1;32m     53\u001B[0m     \u001B[38;5;28;01mfor\u001B[39;00m page_title \u001B[38;5;129;01min\u001B[39;00m page_titles[: \u001B[38;5;28mself\u001B[39m\u001B[38;5;241m.\u001B[39mtop_k_results]:\n",
      "File \u001B[0;32m/opt/anaconda3/envs/ai_312/lib/python3.12/site-packages/wikipedia/util.py:28\u001B[0m, in \u001B[0;36mcache.__call__\u001B[0;34m(self, *args, **kwargs)\u001B[0m\n\u001B[1;32m     26\u001B[0m   ret \u001B[38;5;241m=\u001B[39m \u001B[38;5;28mself\u001B[39m\u001B[38;5;241m.\u001B[39m_cache[key]\n\u001B[1;32m     27\u001B[0m \u001B[38;5;28;01melse\u001B[39;00m:\n\u001B[0;32m---> 28\u001B[0m   ret \u001B[38;5;241m=\u001B[39m \u001B[38;5;28mself\u001B[39m\u001B[38;5;241m.\u001B[39m_cache[key] \u001B[38;5;241m=\u001B[39m \u001B[38;5;28mself\u001B[39m\u001B[38;5;241m.\u001B[39mfn(\u001B[38;5;241m*\u001B[39margs, \u001B[38;5;241m*\u001B[39m\u001B[38;5;241m*\u001B[39mkwargs)\n\u001B[1;32m     30\u001B[0m \u001B[38;5;28;01mreturn\u001B[39;00m ret\n",
      "File \u001B[0;32m/opt/anaconda3/envs/ai_312/lib/python3.12/site-packages/wikipedia/wikipedia.py:103\u001B[0m, in \u001B[0;36msearch\u001B[0;34m(query, results, suggestion)\u001B[0m\n\u001B[1;32m    100\u001B[0m \u001B[38;5;28;01mif\u001B[39;00m suggestion:\n\u001B[1;32m    101\u001B[0m   search_params[\u001B[38;5;124m'\u001B[39m\u001B[38;5;124msrinfo\u001B[39m\u001B[38;5;124m'\u001B[39m] \u001B[38;5;241m=\u001B[39m \u001B[38;5;124m'\u001B[39m\u001B[38;5;124msuggestion\u001B[39m\u001B[38;5;124m'\u001B[39m\n\u001B[0;32m--> 103\u001B[0m raw_results \u001B[38;5;241m=\u001B[39m _wiki_request(search_params)\n\u001B[1;32m    105\u001B[0m \u001B[38;5;28;01mif\u001B[39;00m \u001B[38;5;124m'\u001B[39m\u001B[38;5;124merror\u001B[39m\u001B[38;5;124m'\u001B[39m \u001B[38;5;129;01min\u001B[39;00m raw_results:\n\u001B[1;32m    106\u001B[0m   \u001B[38;5;28;01mif\u001B[39;00m raw_results[\u001B[38;5;124m'\u001B[39m\u001B[38;5;124merror\u001B[39m\u001B[38;5;124m'\u001B[39m][\u001B[38;5;124m'\u001B[39m\u001B[38;5;124minfo\u001B[39m\u001B[38;5;124m'\u001B[39m] \u001B[38;5;129;01min\u001B[39;00m (\u001B[38;5;124m'\u001B[39m\u001B[38;5;124mHTTP request timed out.\u001B[39m\u001B[38;5;124m'\u001B[39m, \u001B[38;5;124m'\u001B[39m\u001B[38;5;124mPool queue is full\u001B[39m\u001B[38;5;124m'\u001B[39m):\n",
      "File \u001B[0;32m/opt/anaconda3/envs/ai_312/lib/python3.12/site-packages/wikipedia/wikipedia.py:737\u001B[0m, in \u001B[0;36m_wiki_request\u001B[0;34m(params)\u001B[0m\n\u001B[1;32m    734\u001B[0m   wait_time \u001B[38;5;241m=\u001B[39m (RATE_LIMIT_LAST_CALL \u001B[38;5;241m+\u001B[39m RATE_LIMIT_MIN_WAIT) \u001B[38;5;241m-\u001B[39m datetime\u001B[38;5;241m.\u001B[39mnow()\n\u001B[1;32m    735\u001B[0m   time\u001B[38;5;241m.\u001B[39msleep(\u001B[38;5;28mint\u001B[39m(wait_time\u001B[38;5;241m.\u001B[39mtotal_seconds()))\n\u001B[0;32m--> 737\u001B[0m r \u001B[38;5;241m=\u001B[39m requests\u001B[38;5;241m.\u001B[39mget(API_URL, params\u001B[38;5;241m=\u001B[39mparams, headers\u001B[38;5;241m=\u001B[39mheaders)\n\u001B[1;32m    739\u001B[0m \u001B[38;5;28;01mif\u001B[39;00m RATE_LIMIT:\n\u001B[1;32m    740\u001B[0m   RATE_LIMIT_LAST_CALL \u001B[38;5;241m=\u001B[39m datetime\u001B[38;5;241m.\u001B[39mnow()\n",
      "File \u001B[0;32m/opt/anaconda3/envs/ai_312/lib/python3.12/site-packages/requests/api.py:73\u001B[0m, in \u001B[0;36mget\u001B[0;34m(url, params, **kwargs)\u001B[0m\n\u001B[1;32m     62\u001B[0m \u001B[38;5;28;01mdef\u001B[39;00m \u001B[38;5;21mget\u001B[39m(url, params\u001B[38;5;241m=\u001B[39m\u001B[38;5;28;01mNone\u001B[39;00m, \u001B[38;5;241m*\u001B[39m\u001B[38;5;241m*\u001B[39mkwargs):\n\u001B[1;32m     63\u001B[0m \u001B[38;5;250m    \u001B[39m\u001B[38;5;124mr\u001B[39m\u001B[38;5;124;03m\"\"\"Sends a GET request.\u001B[39;00m\n\u001B[1;32m     64\u001B[0m \n\u001B[1;32m     65\u001B[0m \u001B[38;5;124;03m    :param url: URL for the new :class:`Request` object.\u001B[39;00m\n\u001B[0;32m   (...)\u001B[0m\n\u001B[1;32m     70\u001B[0m \u001B[38;5;124;03m    :rtype: requests.Response\u001B[39;00m\n\u001B[1;32m     71\u001B[0m \u001B[38;5;124;03m    \"\"\"\u001B[39;00m\n\u001B[0;32m---> 73\u001B[0m     \u001B[38;5;28;01mreturn\u001B[39;00m request(\u001B[38;5;124m\"\u001B[39m\u001B[38;5;124mget\u001B[39m\u001B[38;5;124m\"\u001B[39m, url, params\u001B[38;5;241m=\u001B[39mparams, \u001B[38;5;241m*\u001B[39m\u001B[38;5;241m*\u001B[39mkwargs)\n",
      "File \u001B[0;32m/opt/anaconda3/envs/ai_312/lib/python3.12/site-packages/requests/api.py:59\u001B[0m, in \u001B[0;36mrequest\u001B[0;34m(method, url, **kwargs)\u001B[0m\n\u001B[1;32m     55\u001B[0m \u001B[38;5;66;03m# By using the 'with' statement we are sure the session is closed, thus we\u001B[39;00m\n\u001B[1;32m     56\u001B[0m \u001B[38;5;66;03m# avoid leaving sockets open which can trigger a ResourceWarning in some\u001B[39;00m\n\u001B[1;32m     57\u001B[0m \u001B[38;5;66;03m# cases, and look like a memory leak in others.\u001B[39;00m\n\u001B[1;32m     58\u001B[0m \u001B[38;5;28;01mwith\u001B[39;00m sessions\u001B[38;5;241m.\u001B[39mSession() \u001B[38;5;28;01mas\u001B[39;00m session:\n\u001B[0;32m---> 59\u001B[0m     \u001B[38;5;28;01mreturn\u001B[39;00m session\u001B[38;5;241m.\u001B[39mrequest(method\u001B[38;5;241m=\u001B[39mmethod, url\u001B[38;5;241m=\u001B[39murl, \u001B[38;5;241m*\u001B[39m\u001B[38;5;241m*\u001B[39mkwargs)\n",
      "File \u001B[0;32m/opt/anaconda3/envs/ai_312/lib/python3.12/site-packages/requests/sessions.py:589\u001B[0m, in \u001B[0;36mSession.request\u001B[0;34m(self, method, url, params, data, headers, cookies, files, auth, timeout, allow_redirects, proxies, hooks, stream, verify, cert, json)\u001B[0m\n\u001B[1;32m    584\u001B[0m send_kwargs \u001B[38;5;241m=\u001B[39m {\n\u001B[1;32m    585\u001B[0m     \u001B[38;5;124m\"\u001B[39m\u001B[38;5;124mtimeout\u001B[39m\u001B[38;5;124m\"\u001B[39m: timeout,\n\u001B[1;32m    586\u001B[0m     \u001B[38;5;124m\"\u001B[39m\u001B[38;5;124mallow_redirects\u001B[39m\u001B[38;5;124m\"\u001B[39m: allow_redirects,\n\u001B[1;32m    587\u001B[0m }\n\u001B[1;32m    588\u001B[0m send_kwargs\u001B[38;5;241m.\u001B[39mupdate(settings)\n\u001B[0;32m--> 589\u001B[0m resp \u001B[38;5;241m=\u001B[39m \u001B[38;5;28mself\u001B[39m\u001B[38;5;241m.\u001B[39msend(prep, \u001B[38;5;241m*\u001B[39m\u001B[38;5;241m*\u001B[39msend_kwargs)\n\u001B[1;32m    591\u001B[0m \u001B[38;5;28;01mreturn\u001B[39;00m resp\n",
      "File \u001B[0;32m/opt/anaconda3/envs/ai_312/lib/python3.12/site-packages/requests/sessions.py:703\u001B[0m, in \u001B[0;36mSession.send\u001B[0;34m(self, request, **kwargs)\u001B[0m\n\u001B[1;32m    700\u001B[0m start \u001B[38;5;241m=\u001B[39m preferred_clock()\n\u001B[1;32m    702\u001B[0m \u001B[38;5;66;03m# Send the request\u001B[39;00m\n\u001B[0;32m--> 703\u001B[0m r \u001B[38;5;241m=\u001B[39m adapter\u001B[38;5;241m.\u001B[39msend(request, \u001B[38;5;241m*\u001B[39m\u001B[38;5;241m*\u001B[39mkwargs)\n\u001B[1;32m    705\u001B[0m \u001B[38;5;66;03m# Total elapsed time of the request (approximately)\u001B[39;00m\n\u001B[1;32m    706\u001B[0m elapsed \u001B[38;5;241m=\u001B[39m preferred_clock() \u001B[38;5;241m-\u001B[39m start\n",
      "File \u001B[0;32m/opt/anaconda3/envs/ai_312/lib/python3.12/site-packages/requests/adapters.py:688\u001B[0m, in \u001B[0;36mHTTPAdapter.send\u001B[0;34m(self, request, stream, timeout, verify, cert, proxies)\u001B[0m\n\u001B[1;32m    685\u001B[0m \u001B[38;5;28;01mif\u001B[39;00m \u001B[38;5;28misinstance\u001B[39m(e\u001B[38;5;241m.\u001B[39mreason, ConnectTimeoutError):\n\u001B[1;32m    686\u001B[0m     \u001B[38;5;66;03m# TODO: Remove this in 3.0.0: see #2811\u001B[39;00m\n\u001B[1;32m    687\u001B[0m     \u001B[38;5;28;01mif\u001B[39;00m \u001B[38;5;129;01mnot\u001B[39;00m \u001B[38;5;28misinstance\u001B[39m(e\u001B[38;5;241m.\u001B[39mreason, NewConnectionError):\n\u001B[0;32m--> 688\u001B[0m         \u001B[38;5;28;01mraise\u001B[39;00m ConnectTimeout(e, request\u001B[38;5;241m=\u001B[39mrequest)\n\u001B[1;32m    690\u001B[0m \u001B[38;5;28;01mif\u001B[39;00m \u001B[38;5;28misinstance\u001B[39m(e\u001B[38;5;241m.\u001B[39mreason, ResponseError):\n\u001B[1;32m    691\u001B[0m     \u001B[38;5;28;01mraise\u001B[39;00m RetryError(e, request\u001B[38;5;241m=\u001B[39mrequest)\n",
      "\u001B[0;31mConnectTimeout\u001B[0m: HTTPConnectionPool(host='en.wikipedia.org', port=80): Max retries exceeded with url: /w/api.php?list=search&srprop=&srlimit=1&limit=1&srsearch=langchain&format=json&action=query (Caused by ConnectTimeoutError(<urllib3.connection.HTTPConnection object at 0x110d94980>, 'Connection to en.wikipedia.org timed out. (connect timeout=None)'))"
     ]
    }
   ],
   "source": [
    "from langchain_community.tools import WikipediaQueryRun\n",
    "from langchain_community.utilities import WikipediaAPIWrapper\n",
    "\n",
    "api_wrapper = WikipediaAPIWrapper(top_k_results=1, doc_content_chars_max=100)\n",
    "tool = WikipediaQueryRun(api_wrapper=api_wrapper)\n",
    "\n",
    "print(tool.invoke({\"query\": \"langchain\"}))"
   ],
   "metadata": {
    "collapsed": false,
    "ExecuteTime": {
     "end_time": "2024-10-31T05:47:38.863370Z",
     "start_time": "2024-10-31T05:46:22.433922Z"
    }
   },
   "id": "6b56d663cebbf677",
   "execution_count": 2
  },
  {
   "cell_type": "markdown",
   "source": [
    "## 自定义默认工具\n",
    "\n"
   ],
   "metadata": {
    "collapsed": false
   },
   "id": "72e7785d88ca20bd"
  },
  {
   "cell_type": "code",
   "outputs": [
    {
     "ename": "KeyboardInterrupt",
     "evalue": "",
     "output_type": "error",
     "traceback": [
      "\u001B[0;31m---------------------------------------------------------------------------\u001B[0m",
      "\u001B[0;31mKeyboardInterrupt\u001B[0m                         Traceback (most recent call last)",
      "Cell \u001B[0;32mIn[3], line 22\u001B[0m\n\u001B[1;32m      9\u001B[0m     query: \u001B[38;5;28mstr\u001B[39m \u001B[38;5;241m=\u001B[39m Field(\n\u001B[1;32m     10\u001B[0m         description\u001B[38;5;241m=\u001B[39m\u001B[38;5;124m\"\u001B[39m\u001B[38;5;124mquery to look up in Wikipedia, should be 3 or less words\u001B[39m\u001B[38;5;124m\"\u001B[39m\n\u001B[1;32m     11\u001B[0m     )\n\u001B[1;32m     14\u001B[0m tool \u001B[38;5;241m=\u001B[39m WikipediaQueryRun(\n\u001B[1;32m     15\u001B[0m     name\u001B[38;5;241m=\u001B[39m\u001B[38;5;124m\"\u001B[39m\u001B[38;5;124mwiki-tool\u001B[39m\u001B[38;5;124m\"\u001B[39m,\n\u001B[1;32m     16\u001B[0m     description\u001B[38;5;241m=\u001B[39m\u001B[38;5;124m\"\u001B[39m\u001B[38;5;124mlook up things in wikipedia\u001B[39m\u001B[38;5;124m\"\u001B[39m,\n\u001B[0;32m   (...)\u001B[0m\n\u001B[1;32m     19\u001B[0m     return_direct\u001B[38;5;241m=\u001B[39m\u001B[38;5;28;01mTrue\u001B[39;00m,\n\u001B[1;32m     20\u001B[0m )\n\u001B[0;32m---> 22\u001B[0m \u001B[38;5;28mprint\u001B[39m(tool\u001B[38;5;241m.\u001B[39mrun(\u001B[38;5;124m\"\u001B[39m\u001B[38;5;124mlangchain\u001B[39m\u001B[38;5;124m\"\u001B[39m))\n",
      "File \u001B[0;32m/opt/anaconda3/envs/ai_312/lib/python3.12/site-packages/langchain_core/tools/base.py:689\u001B[0m, in \u001B[0;36mBaseTool.run\u001B[0;34m(self, tool_input, verbose, start_color, color, callbacks, tags, metadata, run_name, run_id, config, tool_call_id, **kwargs)\u001B[0m\n\u001B[1;32m    687\u001B[0m \u001B[38;5;28;01mif\u001B[39;00m error_to_raise:\n\u001B[1;32m    688\u001B[0m     run_manager\u001B[38;5;241m.\u001B[39mon_tool_error(error_to_raise)\n\u001B[0;32m--> 689\u001B[0m     \u001B[38;5;28;01mraise\u001B[39;00m error_to_raise\n\u001B[1;32m    690\u001B[0m output \u001B[38;5;241m=\u001B[39m _format_output(content, artifact, tool_call_id, \u001B[38;5;28mself\u001B[39m\u001B[38;5;241m.\u001B[39mname, status)\n\u001B[1;32m    691\u001B[0m run_manager\u001B[38;5;241m.\u001B[39mon_tool_end(output, color\u001B[38;5;241m=\u001B[39mcolor, name\u001B[38;5;241m=\u001B[39m\u001B[38;5;28mself\u001B[39m\u001B[38;5;241m.\u001B[39mname, \u001B[38;5;241m*\u001B[39m\u001B[38;5;241m*\u001B[39mkwargs)\n",
      "File \u001B[0;32m/opt/anaconda3/envs/ai_312/lib/python3.12/site-packages/langchain_core/tools/base.py:657\u001B[0m, in \u001B[0;36mBaseTool.run\u001B[0;34m(self, tool_input, verbose, start_color, color, callbacks, tags, metadata, run_name, run_id, config, tool_call_id, **kwargs)\u001B[0m\n\u001B[1;32m    655\u001B[0m \u001B[38;5;28;01mif\u001B[39;00m config_param \u001B[38;5;241m:=\u001B[39m _get_runnable_config_param(\u001B[38;5;28mself\u001B[39m\u001B[38;5;241m.\u001B[39m_run):\n\u001B[1;32m    656\u001B[0m     tool_kwargs[config_param] \u001B[38;5;241m=\u001B[39m config\n\u001B[0;32m--> 657\u001B[0m response \u001B[38;5;241m=\u001B[39m context\u001B[38;5;241m.\u001B[39mrun(\u001B[38;5;28mself\u001B[39m\u001B[38;5;241m.\u001B[39m_run, \u001B[38;5;241m*\u001B[39mtool_args, \u001B[38;5;241m*\u001B[39m\u001B[38;5;241m*\u001B[39mtool_kwargs)\n\u001B[1;32m    658\u001B[0m \u001B[38;5;28;01mif\u001B[39;00m \u001B[38;5;28mself\u001B[39m\u001B[38;5;241m.\u001B[39mresponse_format \u001B[38;5;241m==\u001B[39m \u001B[38;5;124m\"\u001B[39m\u001B[38;5;124mcontent_and_artifact\u001B[39m\u001B[38;5;124m\"\u001B[39m:\n\u001B[1;32m    659\u001B[0m     \u001B[38;5;28;01mif\u001B[39;00m \u001B[38;5;129;01mnot\u001B[39;00m \u001B[38;5;28misinstance\u001B[39m(response, \u001B[38;5;28mtuple\u001B[39m) \u001B[38;5;129;01mor\u001B[39;00m \u001B[38;5;28mlen\u001B[39m(response) \u001B[38;5;241m!=\u001B[39m \u001B[38;5;241m2\u001B[39m:\n",
      "File \u001B[0;32m/opt/anaconda3/envs/ai_312/lib/python3.12/site-packages/langchain_community/tools/wikipedia/tool.py:38\u001B[0m, in \u001B[0;36mWikipediaQueryRun._run\u001B[0;34m(self, query, run_manager)\u001B[0m\n\u001B[1;32m     32\u001B[0m \u001B[38;5;28;01mdef\u001B[39;00m \u001B[38;5;21m_run\u001B[39m(\n\u001B[1;32m     33\u001B[0m     \u001B[38;5;28mself\u001B[39m,\n\u001B[1;32m     34\u001B[0m     query: \u001B[38;5;28mstr\u001B[39m,\n\u001B[1;32m     35\u001B[0m     run_manager: Optional[CallbackManagerForToolRun] \u001B[38;5;241m=\u001B[39m \u001B[38;5;28;01mNone\u001B[39;00m,\n\u001B[1;32m     36\u001B[0m ) \u001B[38;5;241m-\u001B[39m\u001B[38;5;241m>\u001B[39m \u001B[38;5;28mstr\u001B[39m:\n\u001B[1;32m     37\u001B[0m \u001B[38;5;250m    \u001B[39m\u001B[38;5;124;03m\"\"\"Use the Wikipedia tool.\"\"\"\u001B[39;00m\n\u001B[0;32m---> 38\u001B[0m     \u001B[38;5;28;01mreturn\u001B[39;00m \u001B[38;5;28mself\u001B[39m\u001B[38;5;241m.\u001B[39mapi_wrapper\u001B[38;5;241m.\u001B[39mrun(query)\n",
      "File \u001B[0;32m/opt/anaconda3/envs/ai_312/lib/python3.12/site-packages/langchain_community/utilities/wikipedia.py:49\u001B[0m, in \u001B[0;36mWikipediaAPIWrapper.run\u001B[0;34m(self, query)\u001B[0m\n\u001B[1;32m     47\u001B[0m \u001B[38;5;28;01mdef\u001B[39;00m \u001B[38;5;21mrun\u001B[39m(\u001B[38;5;28mself\u001B[39m, query: \u001B[38;5;28mstr\u001B[39m) \u001B[38;5;241m-\u001B[39m\u001B[38;5;241m>\u001B[39m \u001B[38;5;28mstr\u001B[39m:\n\u001B[1;32m     48\u001B[0m \u001B[38;5;250m    \u001B[39m\u001B[38;5;124;03m\"\"\"Run Wikipedia search and get page summaries.\"\"\"\u001B[39;00m\n\u001B[0;32m---> 49\u001B[0m     page_titles \u001B[38;5;241m=\u001B[39m \u001B[38;5;28mself\u001B[39m\u001B[38;5;241m.\u001B[39mwiki_client\u001B[38;5;241m.\u001B[39msearch(\n\u001B[1;32m     50\u001B[0m         query[:WIKIPEDIA_MAX_QUERY_LENGTH], results\u001B[38;5;241m=\u001B[39m\u001B[38;5;28mself\u001B[39m\u001B[38;5;241m.\u001B[39mtop_k_results\n\u001B[1;32m     51\u001B[0m     )\n\u001B[1;32m     52\u001B[0m     summaries \u001B[38;5;241m=\u001B[39m []\n\u001B[1;32m     53\u001B[0m     \u001B[38;5;28;01mfor\u001B[39;00m page_title \u001B[38;5;129;01min\u001B[39;00m page_titles[: \u001B[38;5;28mself\u001B[39m\u001B[38;5;241m.\u001B[39mtop_k_results]:\n",
      "File \u001B[0;32m/opt/anaconda3/envs/ai_312/lib/python3.12/site-packages/wikipedia/util.py:28\u001B[0m, in \u001B[0;36mcache.__call__\u001B[0;34m(self, *args, **kwargs)\u001B[0m\n\u001B[1;32m     26\u001B[0m   ret \u001B[38;5;241m=\u001B[39m \u001B[38;5;28mself\u001B[39m\u001B[38;5;241m.\u001B[39m_cache[key]\n\u001B[1;32m     27\u001B[0m \u001B[38;5;28;01melse\u001B[39;00m:\n\u001B[0;32m---> 28\u001B[0m   ret \u001B[38;5;241m=\u001B[39m \u001B[38;5;28mself\u001B[39m\u001B[38;5;241m.\u001B[39m_cache[key] \u001B[38;5;241m=\u001B[39m \u001B[38;5;28mself\u001B[39m\u001B[38;5;241m.\u001B[39mfn(\u001B[38;5;241m*\u001B[39margs, \u001B[38;5;241m*\u001B[39m\u001B[38;5;241m*\u001B[39mkwargs)\n\u001B[1;32m     30\u001B[0m \u001B[38;5;28;01mreturn\u001B[39;00m ret\n",
      "File \u001B[0;32m/opt/anaconda3/envs/ai_312/lib/python3.12/site-packages/wikipedia/wikipedia.py:103\u001B[0m, in \u001B[0;36msearch\u001B[0;34m(query, results, suggestion)\u001B[0m\n\u001B[1;32m    100\u001B[0m \u001B[38;5;28;01mif\u001B[39;00m suggestion:\n\u001B[1;32m    101\u001B[0m   search_params[\u001B[38;5;124m'\u001B[39m\u001B[38;5;124msrinfo\u001B[39m\u001B[38;5;124m'\u001B[39m] \u001B[38;5;241m=\u001B[39m \u001B[38;5;124m'\u001B[39m\u001B[38;5;124msuggestion\u001B[39m\u001B[38;5;124m'\u001B[39m\n\u001B[0;32m--> 103\u001B[0m raw_results \u001B[38;5;241m=\u001B[39m _wiki_request(search_params)\n\u001B[1;32m    105\u001B[0m \u001B[38;5;28;01mif\u001B[39;00m \u001B[38;5;124m'\u001B[39m\u001B[38;5;124merror\u001B[39m\u001B[38;5;124m'\u001B[39m \u001B[38;5;129;01min\u001B[39;00m raw_results:\n\u001B[1;32m    106\u001B[0m   \u001B[38;5;28;01mif\u001B[39;00m raw_results[\u001B[38;5;124m'\u001B[39m\u001B[38;5;124merror\u001B[39m\u001B[38;5;124m'\u001B[39m][\u001B[38;5;124m'\u001B[39m\u001B[38;5;124minfo\u001B[39m\u001B[38;5;124m'\u001B[39m] \u001B[38;5;129;01min\u001B[39;00m (\u001B[38;5;124m'\u001B[39m\u001B[38;5;124mHTTP request timed out.\u001B[39m\u001B[38;5;124m'\u001B[39m, \u001B[38;5;124m'\u001B[39m\u001B[38;5;124mPool queue is full\u001B[39m\u001B[38;5;124m'\u001B[39m):\n",
      "File \u001B[0;32m/opt/anaconda3/envs/ai_312/lib/python3.12/site-packages/wikipedia/wikipedia.py:737\u001B[0m, in \u001B[0;36m_wiki_request\u001B[0;34m(params)\u001B[0m\n\u001B[1;32m    734\u001B[0m   wait_time \u001B[38;5;241m=\u001B[39m (RATE_LIMIT_LAST_CALL \u001B[38;5;241m+\u001B[39m RATE_LIMIT_MIN_WAIT) \u001B[38;5;241m-\u001B[39m datetime\u001B[38;5;241m.\u001B[39mnow()\n\u001B[1;32m    735\u001B[0m   time\u001B[38;5;241m.\u001B[39msleep(\u001B[38;5;28mint\u001B[39m(wait_time\u001B[38;5;241m.\u001B[39mtotal_seconds()))\n\u001B[0;32m--> 737\u001B[0m r \u001B[38;5;241m=\u001B[39m requests\u001B[38;5;241m.\u001B[39mget(API_URL, params\u001B[38;5;241m=\u001B[39mparams, headers\u001B[38;5;241m=\u001B[39mheaders)\n\u001B[1;32m    739\u001B[0m \u001B[38;5;28;01mif\u001B[39;00m RATE_LIMIT:\n\u001B[1;32m    740\u001B[0m   RATE_LIMIT_LAST_CALL \u001B[38;5;241m=\u001B[39m datetime\u001B[38;5;241m.\u001B[39mnow()\n",
      "File \u001B[0;32m/opt/anaconda3/envs/ai_312/lib/python3.12/site-packages/requests/api.py:73\u001B[0m, in \u001B[0;36mget\u001B[0;34m(url, params, **kwargs)\u001B[0m\n\u001B[1;32m     62\u001B[0m \u001B[38;5;28;01mdef\u001B[39;00m \u001B[38;5;21mget\u001B[39m(url, params\u001B[38;5;241m=\u001B[39m\u001B[38;5;28;01mNone\u001B[39;00m, \u001B[38;5;241m*\u001B[39m\u001B[38;5;241m*\u001B[39mkwargs):\n\u001B[1;32m     63\u001B[0m \u001B[38;5;250m    \u001B[39m\u001B[38;5;124mr\u001B[39m\u001B[38;5;124;03m\"\"\"Sends a GET request.\u001B[39;00m\n\u001B[1;32m     64\u001B[0m \n\u001B[1;32m     65\u001B[0m \u001B[38;5;124;03m    :param url: URL for the new :class:`Request` object.\u001B[39;00m\n\u001B[0;32m   (...)\u001B[0m\n\u001B[1;32m     70\u001B[0m \u001B[38;5;124;03m    :rtype: requests.Response\u001B[39;00m\n\u001B[1;32m     71\u001B[0m \u001B[38;5;124;03m    \"\"\"\u001B[39;00m\n\u001B[0;32m---> 73\u001B[0m     \u001B[38;5;28;01mreturn\u001B[39;00m request(\u001B[38;5;124m\"\u001B[39m\u001B[38;5;124mget\u001B[39m\u001B[38;5;124m\"\u001B[39m, url, params\u001B[38;5;241m=\u001B[39mparams, \u001B[38;5;241m*\u001B[39m\u001B[38;5;241m*\u001B[39mkwargs)\n",
      "File \u001B[0;32m/opt/anaconda3/envs/ai_312/lib/python3.12/site-packages/requests/api.py:59\u001B[0m, in \u001B[0;36mrequest\u001B[0;34m(method, url, **kwargs)\u001B[0m\n\u001B[1;32m     55\u001B[0m \u001B[38;5;66;03m# By using the 'with' statement we are sure the session is closed, thus we\u001B[39;00m\n\u001B[1;32m     56\u001B[0m \u001B[38;5;66;03m# avoid leaving sockets open which can trigger a ResourceWarning in some\u001B[39;00m\n\u001B[1;32m     57\u001B[0m \u001B[38;5;66;03m# cases, and look like a memory leak in others.\u001B[39;00m\n\u001B[1;32m     58\u001B[0m \u001B[38;5;28;01mwith\u001B[39;00m sessions\u001B[38;5;241m.\u001B[39mSession() \u001B[38;5;28;01mas\u001B[39;00m session:\n\u001B[0;32m---> 59\u001B[0m     \u001B[38;5;28;01mreturn\u001B[39;00m session\u001B[38;5;241m.\u001B[39mrequest(method\u001B[38;5;241m=\u001B[39mmethod, url\u001B[38;5;241m=\u001B[39murl, \u001B[38;5;241m*\u001B[39m\u001B[38;5;241m*\u001B[39mkwargs)\n",
      "File \u001B[0;32m/opt/anaconda3/envs/ai_312/lib/python3.12/site-packages/requests/sessions.py:589\u001B[0m, in \u001B[0;36mSession.request\u001B[0;34m(self, method, url, params, data, headers, cookies, files, auth, timeout, allow_redirects, proxies, hooks, stream, verify, cert, json)\u001B[0m\n\u001B[1;32m    584\u001B[0m send_kwargs \u001B[38;5;241m=\u001B[39m {\n\u001B[1;32m    585\u001B[0m     \u001B[38;5;124m\"\u001B[39m\u001B[38;5;124mtimeout\u001B[39m\u001B[38;5;124m\"\u001B[39m: timeout,\n\u001B[1;32m    586\u001B[0m     \u001B[38;5;124m\"\u001B[39m\u001B[38;5;124mallow_redirects\u001B[39m\u001B[38;5;124m\"\u001B[39m: allow_redirects,\n\u001B[1;32m    587\u001B[0m }\n\u001B[1;32m    588\u001B[0m send_kwargs\u001B[38;5;241m.\u001B[39mupdate(settings)\n\u001B[0;32m--> 589\u001B[0m resp \u001B[38;5;241m=\u001B[39m \u001B[38;5;28mself\u001B[39m\u001B[38;5;241m.\u001B[39msend(prep, \u001B[38;5;241m*\u001B[39m\u001B[38;5;241m*\u001B[39msend_kwargs)\n\u001B[1;32m    591\u001B[0m \u001B[38;5;28;01mreturn\u001B[39;00m resp\n",
      "File \u001B[0;32m/opt/anaconda3/envs/ai_312/lib/python3.12/site-packages/requests/sessions.py:703\u001B[0m, in \u001B[0;36mSession.send\u001B[0;34m(self, request, **kwargs)\u001B[0m\n\u001B[1;32m    700\u001B[0m start \u001B[38;5;241m=\u001B[39m preferred_clock()\n\u001B[1;32m    702\u001B[0m \u001B[38;5;66;03m# Send the request\u001B[39;00m\n\u001B[0;32m--> 703\u001B[0m r \u001B[38;5;241m=\u001B[39m adapter\u001B[38;5;241m.\u001B[39msend(request, \u001B[38;5;241m*\u001B[39m\u001B[38;5;241m*\u001B[39mkwargs)\n\u001B[1;32m    705\u001B[0m \u001B[38;5;66;03m# Total elapsed time of the request (approximately)\u001B[39;00m\n\u001B[1;32m    706\u001B[0m elapsed \u001B[38;5;241m=\u001B[39m preferred_clock() \u001B[38;5;241m-\u001B[39m start\n",
      "File \u001B[0;32m/opt/anaconda3/envs/ai_312/lib/python3.12/site-packages/requests/adapters.py:667\u001B[0m, in \u001B[0;36mHTTPAdapter.send\u001B[0;34m(self, request, stream, timeout, verify, cert, proxies)\u001B[0m\n\u001B[1;32m    664\u001B[0m     timeout \u001B[38;5;241m=\u001B[39m TimeoutSauce(connect\u001B[38;5;241m=\u001B[39mtimeout, read\u001B[38;5;241m=\u001B[39mtimeout)\n\u001B[1;32m    666\u001B[0m \u001B[38;5;28;01mtry\u001B[39;00m:\n\u001B[0;32m--> 667\u001B[0m     resp \u001B[38;5;241m=\u001B[39m conn\u001B[38;5;241m.\u001B[39murlopen(\n\u001B[1;32m    668\u001B[0m         method\u001B[38;5;241m=\u001B[39mrequest\u001B[38;5;241m.\u001B[39mmethod,\n\u001B[1;32m    669\u001B[0m         url\u001B[38;5;241m=\u001B[39murl,\n\u001B[1;32m    670\u001B[0m         body\u001B[38;5;241m=\u001B[39mrequest\u001B[38;5;241m.\u001B[39mbody,\n\u001B[1;32m    671\u001B[0m         headers\u001B[38;5;241m=\u001B[39mrequest\u001B[38;5;241m.\u001B[39mheaders,\n\u001B[1;32m    672\u001B[0m         redirect\u001B[38;5;241m=\u001B[39m\u001B[38;5;28;01mFalse\u001B[39;00m,\n\u001B[1;32m    673\u001B[0m         assert_same_host\u001B[38;5;241m=\u001B[39m\u001B[38;5;28;01mFalse\u001B[39;00m,\n\u001B[1;32m    674\u001B[0m         preload_content\u001B[38;5;241m=\u001B[39m\u001B[38;5;28;01mFalse\u001B[39;00m,\n\u001B[1;32m    675\u001B[0m         decode_content\u001B[38;5;241m=\u001B[39m\u001B[38;5;28;01mFalse\u001B[39;00m,\n\u001B[1;32m    676\u001B[0m         retries\u001B[38;5;241m=\u001B[39m\u001B[38;5;28mself\u001B[39m\u001B[38;5;241m.\u001B[39mmax_retries,\n\u001B[1;32m    677\u001B[0m         timeout\u001B[38;5;241m=\u001B[39mtimeout,\n\u001B[1;32m    678\u001B[0m         chunked\u001B[38;5;241m=\u001B[39mchunked,\n\u001B[1;32m    679\u001B[0m     )\n\u001B[1;32m    681\u001B[0m \u001B[38;5;28;01mexcept\u001B[39;00m (ProtocolError, \u001B[38;5;167;01mOSError\u001B[39;00m) \u001B[38;5;28;01mas\u001B[39;00m err:\n\u001B[1;32m    682\u001B[0m     \u001B[38;5;28;01mraise\u001B[39;00m \u001B[38;5;167;01mConnectionError\u001B[39;00m(err, request\u001B[38;5;241m=\u001B[39mrequest)\n",
      "File \u001B[0;32m/opt/anaconda3/envs/ai_312/lib/python3.12/site-packages/urllib3/connectionpool.py:789\u001B[0m, in \u001B[0;36mHTTPConnectionPool.urlopen\u001B[0;34m(self, method, url, body, headers, retries, redirect, assert_same_host, timeout, pool_timeout, release_conn, chunked, body_pos, preload_content, decode_content, **response_kw)\u001B[0m\n\u001B[1;32m    786\u001B[0m response_conn \u001B[38;5;241m=\u001B[39m conn \u001B[38;5;28;01mif\u001B[39;00m \u001B[38;5;129;01mnot\u001B[39;00m release_conn \u001B[38;5;28;01melse\u001B[39;00m \u001B[38;5;28;01mNone\u001B[39;00m\n\u001B[1;32m    788\u001B[0m \u001B[38;5;66;03m# Make the request on the HTTPConnection object\u001B[39;00m\n\u001B[0;32m--> 789\u001B[0m response \u001B[38;5;241m=\u001B[39m \u001B[38;5;28mself\u001B[39m\u001B[38;5;241m.\u001B[39m_make_request(\n\u001B[1;32m    790\u001B[0m     conn,\n\u001B[1;32m    791\u001B[0m     method,\n\u001B[1;32m    792\u001B[0m     url,\n\u001B[1;32m    793\u001B[0m     timeout\u001B[38;5;241m=\u001B[39mtimeout_obj,\n\u001B[1;32m    794\u001B[0m     body\u001B[38;5;241m=\u001B[39mbody,\n\u001B[1;32m    795\u001B[0m     headers\u001B[38;5;241m=\u001B[39mheaders,\n\u001B[1;32m    796\u001B[0m     chunked\u001B[38;5;241m=\u001B[39mchunked,\n\u001B[1;32m    797\u001B[0m     retries\u001B[38;5;241m=\u001B[39mretries,\n\u001B[1;32m    798\u001B[0m     response_conn\u001B[38;5;241m=\u001B[39mresponse_conn,\n\u001B[1;32m    799\u001B[0m     preload_content\u001B[38;5;241m=\u001B[39mpreload_content,\n\u001B[1;32m    800\u001B[0m     decode_content\u001B[38;5;241m=\u001B[39mdecode_content,\n\u001B[1;32m    801\u001B[0m     \u001B[38;5;241m*\u001B[39m\u001B[38;5;241m*\u001B[39mresponse_kw,\n\u001B[1;32m    802\u001B[0m )\n\u001B[1;32m    804\u001B[0m \u001B[38;5;66;03m# Everything went great!\u001B[39;00m\n\u001B[1;32m    805\u001B[0m clean_exit \u001B[38;5;241m=\u001B[39m \u001B[38;5;28;01mTrue\u001B[39;00m\n",
      "File \u001B[0;32m/opt/anaconda3/envs/ai_312/lib/python3.12/site-packages/urllib3/connectionpool.py:495\u001B[0m, in \u001B[0;36mHTTPConnectionPool._make_request\u001B[0;34m(self, conn, method, url, body, headers, retries, timeout, chunked, response_conn, preload_content, decode_content, enforce_content_length)\u001B[0m\n\u001B[1;32m    492\u001B[0m \u001B[38;5;66;03m# conn.request() calls http.client.*.request, not the method in\u001B[39;00m\n\u001B[1;32m    493\u001B[0m \u001B[38;5;66;03m# urllib3.request. It also calls makefile (recv) on the socket.\u001B[39;00m\n\u001B[1;32m    494\u001B[0m \u001B[38;5;28;01mtry\u001B[39;00m:\n\u001B[0;32m--> 495\u001B[0m     conn\u001B[38;5;241m.\u001B[39mrequest(\n\u001B[1;32m    496\u001B[0m         method,\n\u001B[1;32m    497\u001B[0m         url,\n\u001B[1;32m    498\u001B[0m         body\u001B[38;5;241m=\u001B[39mbody,\n\u001B[1;32m    499\u001B[0m         headers\u001B[38;5;241m=\u001B[39mheaders,\n\u001B[1;32m    500\u001B[0m         chunked\u001B[38;5;241m=\u001B[39mchunked,\n\u001B[1;32m    501\u001B[0m         preload_content\u001B[38;5;241m=\u001B[39mpreload_content,\n\u001B[1;32m    502\u001B[0m         decode_content\u001B[38;5;241m=\u001B[39mdecode_content,\n\u001B[1;32m    503\u001B[0m         enforce_content_length\u001B[38;5;241m=\u001B[39menforce_content_length,\n\u001B[1;32m    504\u001B[0m     )\n\u001B[1;32m    506\u001B[0m \u001B[38;5;66;03m# We are swallowing BrokenPipeError (errno.EPIPE) since the server is\u001B[39;00m\n\u001B[1;32m    507\u001B[0m \u001B[38;5;66;03m# legitimately able to close the connection after sending a valid response.\u001B[39;00m\n\u001B[1;32m    508\u001B[0m \u001B[38;5;66;03m# With this behaviour, the received response is still readable.\u001B[39;00m\n\u001B[1;32m    509\u001B[0m \u001B[38;5;28;01mexcept\u001B[39;00m \u001B[38;5;167;01mBrokenPipeError\u001B[39;00m:\n",
      "File \u001B[0;32m/opt/anaconda3/envs/ai_312/lib/python3.12/site-packages/urllib3/connection.py:441\u001B[0m, in \u001B[0;36mHTTPConnection.request\u001B[0;34m(self, method, url, body, headers, chunked, preload_content, decode_content, enforce_content_length)\u001B[0m\n\u001B[1;32m    439\u001B[0m \u001B[38;5;28;01mfor\u001B[39;00m header, value \u001B[38;5;129;01min\u001B[39;00m headers\u001B[38;5;241m.\u001B[39mitems():\n\u001B[1;32m    440\u001B[0m     \u001B[38;5;28mself\u001B[39m\u001B[38;5;241m.\u001B[39mputheader(header, value)\n\u001B[0;32m--> 441\u001B[0m \u001B[38;5;28mself\u001B[39m\u001B[38;5;241m.\u001B[39mendheaders()\n\u001B[1;32m    443\u001B[0m \u001B[38;5;66;03m# If we're given a body we start sending that in chunks.\u001B[39;00m\n\u001B[1;32m    444\u001B[0m \u001B[38;5;28;01mif\u001B[39;00m chunks \u001B[38;5;129;01mis\u001B[39;00m \u001B[38;5;129;01mnot\u001B[39;00m \u001B[38;5;28;01mNone\u001B[39;00m:\n",
      "File \u001B[0;32m/opt/anaconda3/envs/ai_312/lib/python3.12/http/client.py:1331\u001B[0m, in \u001B[0;36mHTTPConnection.endheaders\u001B[0;34m(self, message_body, encode_chunked)\u001B[0m\n\u001B[1;32m   1329\u001B[0m \u001B[38;5;28;01melse\u001B[39;00m:\n\u001B[1;32m   1330\u001B[0m     \u001B[38;5;28;01mraise\u001B[39;00m CannotSendHeader()\n\u001B[0;32m-> 1331\u001B[0m \u001B[38;5;28mself\u001B[39m\u001B[38;5;241m.\u001B[39m_send_output(message_body, encode_chunked\u001B[38;5;241m=\u001B[39mencode_chunked)\n",
      "File \u001B[0;32m/opt/anaconda3/envs/ai_312/lib/python3.12/http/client.py:1091\u001B[0m, in \u001B[0;36mHTTPConnection._send_output\u001B[0;34m(self, message_body, encode_chunked)\u001B[0m\n\u001B[1;32m   1089\u001B[0m msg \u001B[38;5;241m=\u001B[39m \u001B[38;5;124mb\u001B[39m\u001B[38;5;124m\"\u001B[39m\u001B[38;5;130;01m\\r\u001B[39;00m\u001B[38;5;130;01m\\n\u001B[39;00m\u001B[38;5;124m\"\u001B[39m\u001B[38;5;241m.\u001B[39mjoin(\u001B[38;5;28mself\u001B[39m\u001B[38;5;241m.\u001B[39m_buffer)\n\u001B[1;32m   1090\u001B[0m \u001B[38;5;28;01mdel\u001B[39;00m \u001B[38;5;28mself\u001B[39m\u001B[38;5;241m.\u001B[39m_buffer[:]\n\u001B[0;32m-> 1091\u001B[0m \u001B[38;5;28mself\u001B[39m\u001B[38;5;241m.\u001B[39msend(msg)\n\u001B[1;32m   1093\u001B[0m \u001B[38;5;28;01mif\u001B[39;00m message_body \u001B[38;5;129;01mis\u001B[39;00m \u001B[38;5;129;01mnot\u001B[39;00m \u001B[38;5;28;01mNone\u001B[39;00m:\n\u001B[1;32m   1094\u001B[0m \n\u001B[1;32m   1095\u001B[0m     \u001B[38;5;66;03m# create a consistent interface to message_body\u001B[39;00m\n\u001B[1;32m   1096\u001B[0m     \u001B[38;5;28;01mif\u001B[39;00m \u001B[38;5;28mhasattr\u001B[39m(message_body, \u001B[38;5;124m'\u001B[39m\u001B[38;5;124mread\u001B[39m\u001B[38;5;124m'\u001B[39m):\n\u001B[1;32m   1097\u001B[0m         \u001B[38;5;66;03m# Let file-like take precedence over byte-like.  This\u001B[39;00m\n\u001B[1;32m   1098\u001B[0m         \u001B[38;5;66;03m# is needed to allow the current position of mmap'ed\u001B[39;00m\n\u001B[1;32m   1099\u001B[0m         \u001B[38;5;66;03m# files to be taken into account.\u001B[39;00m\n",
      "File \u001B[0;32m/opt/anaconda3/envs/ai_312/lib/python3.12/http/client.py:1035\u001B[0m, in \u001B[0;36mHTTPConnection.send\u001B[0;34m(self, data)\u001B[0m\n\u001B[1;32m   1033\u001B[0m \u001B[38;5;28;01mif\u001B[39;00m \u001B[38;5;28mself\u001B[39m\u001B[38;5;241m.\u001B[39msock \u001B[38;5;129;01mis\u001B[39;00m \u001B[38;5;28;01mNone\u001B[39;00m:\n\u001B[1;32m   1034\u001B[0m     \u001B[38;5;28;01mif\u001B[39;00m \u001B[38;5;28mself\u001B[39m\u001B[38;5;241m.\u001B[39mauto_open:\n\u001B[0;32m-> 1035\u001B[0m         \u001B[38;5;28mself\u001B[39m\u001B[38;5;241m.\u001B[39mconnect()\n\u001B[1;32m   1036\u001B[0m     \u001B[38;5;28;01melse\u001B[39;00m:\n\u001B[1;32m   1037\u001B[0m         \u001B[38;5;28;01mraise\u001B[39;00m NotConnected()\n",
      "File \u001B[0;32m/opt/anaconda3/envs/ai_312/lib/python3.12/site-packages/urllib3/connection.py:279\u001B[0m, in \u001B[0;36mHTTPConnection.connect\u001B[0;34m(self)\u001B[0m\n\u001B[1;32m    278\u001B[0m \u001B[38;5;28;01mdef\u001B[39;00m \u001B[38;5;21mconnect\u001B[39m(\u001B[38;5;28mself\u001B[39m) \u001B[38;5;241m-\u001B[39m\u001B[38;5;241m>\u001B[39m \u001B[38;5;28;01mNone\u001B[39;00m:\n\u001B[0;32m--> 279\u001B[0m     \u001B[38;5;28mself\u001B[39m\u001B[38;5;241m.\u001B[39msock \u001B[38;5;241m=\u001B[39m \u001B[38;5;28mself\u001B[39m\u001B[38;5;241m.\u001B[39m_new_conn()\n\u001B[1;32m    280\u001B[0m     \u001B[38;5;28;01mif\u001B[39;00m \u001B[38;5;28mself\u001B[39m\u001B[38;5;241m.\u001B[39m_tunnel_host:\n\u001B[1;32m    281\u001B[0m         \u001B[38;5;66;03m# If we're tunneling it means we're connected to our proxy.\u001B[39;00m\n\u001B[1;32m    282\u001B[0m         \u001B[38;5;28mself\u001B[39m\u001B[38;5;241m.\u001B[39m_has_connected_to_proxy \u001B[38;5;241m=\u001B[39m \u001B[38;5;28;01mTrue\u001B[39;00m\n",
      "File \u001B[0;32m/opt/anaconda3/envs/ai_312/lib/python3.12/site-packages/urllib3/connection.py:199\u001B[0m, in \u001B[0;36mHTTPConnection._new_conn\u001B[0;34m(self)\u001B[0m\n\u001B[1;32m    194\u001B[0m \u001B[38;5;250m\u001B[39m\u001B[38;5;124;03m\"\"\"Establish a socket connection and set nodelay settings on it.\u001B[39;00m\n\u001B[1;32m    195\u001B[0m \n\u001B[1;32m    196\u001B[0m \u001B[38;5;124;03m:return: New socket connection.\u001B[39;00m\n\u001B[1;32m    197\u001B[0m \u001B[38;5;124;03m\"\"\"\u001B[39;00m\n\u001B[1;32m    198\u001B[0m \u001B[38;5;28;01mtry\u001B[39;00m:\n\u001B[0;32m--> 199\u001B[0m     sock \u001B[38;5;241m=\u001B[39m connection\u001B[38;5;241m.\u001B[39mcreate_connection(\n\u001B[1;32m    200\u001B[0m         (\u001B[38;5;28mself\u001B[39m\u001B[38;5;241m.\u001B[39m_dns_host, \u001B[38;5;28mself\u001B[39m\u001B[38;5;241m.\u001B[39mport),\n\u001B[1;32m    201\u001B[0m         \u001B[38;5;28mself\u001B[39m\u001B[38;5;241m.\u001B[39mtimeout,\n\u001B[1;32m    202\u001B[0m         source_address\u001B[38;5;241m=\u001B[39m\u001B[38;5;28mself\u001B[39m\u001B[38;5;241m.\u001B[39msource_address,\n\u001B[1;32m    203\u001B[0m         socket_options\u001B[38;5;241m=\u001B[39m\u001B[38;5;28mself\u001B[39m\u001B[38;5;241m.\u001B[39msocket_options,\n\u001B[1;32m    204\u001B[0m     )\n\u001B[1;32m    205\u001B[0m \u001B[38;5;28;01mexcept\u001B[39;00m socket\u001B[38;5;241m.\u001B[39mgaierror \u001B[38;5;28;01mas\u001B[39;00m e:\n\u001B[1;32m    206\u001B[0m     \u001B[38;5;28;01mraise\u001B[39;00m NameResolutionError(\u001B[38;5;28mself\u001B[39m\u001B[38;5;241m.\u001B[39mhost, \u001B[38;5;28mself\u001B[39m, e) \u001B[38;5;28;01mfrom\u001B[39;00m \u001B[38;5;21;01me\u001B[39;00m\n",
      "File \u001B[0;32m/opt/anaconda3/envs/ai_312/lib/python3.12/site-packages/urllib3/util/connection.py:73\u001B[0m, in \u001B[0;36mcreate_connection\u001B[0;34m(address, timeout, source_address, socket_options)\u001B[0m\n\u001B[1;32m     71\u001B[0m \u001B[38;5;28;01mif\u001B[39;00m source_address:\n\u001B[1;32m     72\u001B[0m     sock\u001B[38;5;241m.\u001B[39mbind(source_address)\n\u001B[0;32m---> 73\u001B[0m sock\u001B[38;5;241m.\u001B[39mconnect(sa)\n\u001B[1;32m     74\u001B[0m \u001B[38;5;66;03m# Break explicitly a reference cycle\u001B[39;00m\n\u001B[1;32m     75\u001B[0m err \u001B[38;5;241m=\u001B[39m \u001B[38;5;28;01mNone\u001B[39;00m\n",
      "\u001B[0;31mKeyboardInterrupt\u001B[0m: "
     ]
    }
   ],
   "source": [
    "from langchain_community.tools import WikipediaQueryRun\n",
    "from pydantic import BaseModel, Field\n",
    "\n",
    "\n",
    "class WikiInputs(BaseModel):\n",
    "    \"\"\"Inputs to the wikipedia tool.\"\"\"\n",
    "\n",
    "    query: str = Field(\n",
    "        description=\"query to look up in Wikipedia, should be 3 or less words\"\n",
    "    )\n",
    "\n",
    "\n",
    "tool = WikipediaQueryRun(\n",
    "    name=\"wiki-tool\",\n",
    "    description=\"look up things in wikipedia\",\n",
    "    args_schema=WikiInputs,\n",
    "    api_wrapper=api_wrapper,\n",
    "    return_direct=True,\n",
    ")\n",
    "\n",
    "print(tool.run(\"langchain\"))"
   ],
   "metadata": {
    "collapsed": false,
    "ExecuteTime": {
     "end_time": "2024-10-31T05:48:42.984600Z",
     "start_time": "2024-10-31T05:47:59.230277Z"
    }
   },
   "id": "594d203ba20cb0bb",
   "execution_count": 3
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 2
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython2",
   "version": "2.7.6"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
